#include "pch.h"
#include "include/baselink.h"
#include "include/netproc.h"
#include "include/protocol.h"
#include "include/crpc.h"

//-------------------------------------------------------------------------------------
BaseLink::BaseLink()
{
	m_pForwardInterface = NULL;
}

BaseLink::~BaseLink()
{

}

static uint8 buffer[4096*100] = { 0 };
bool BaseLink::Send(UINT32 dwConnID, const CProtocol& roPtc)
{
	UINT32  dwType = roPtc.m_dwType;
	UINT32  dwFlag = PTC_TYPE_FLAG;
	int dataSize = roPtc.Serialize(buffer, sizeof(buffer));
	if (dataSize < 0)
	{
		LogError("serialize protocol [%u] failed.", roPtc.m_dwType);
		return false;
	}
	UINT32  dwLength = dataSize + sizeof(UINT32) * 2 + sizeof(SessionType);
	MemoryStream* pMemoryStream = MemoryStream::ObjPool().createObject();
	(*pMemoryStream) << dwLength;
	(*pMemoryStream) << dwType;
	(*pMemoryStream) << dwFlag;
	(*pMemoryStream) << roPtc.m_sessionID;
	pMemoryStream->append(buffer, dataSize);
	LogDebug("CNetProcessor::Send CProtocol dwType:%u, dataSize:%d,dwLength:%u, protoSize:%u", dwType, pMemoryStream->length(), dwLength, dataSize);
	bool result = CNetProcessor::Instance()->Send(dwConnID, pMemoryStream->data(), pMemoryStream->length());
	MemoryStream::ObjPool().reclaimObject(pMemoryStream);
	return result;
}

bool BaseLink::Send(UINT32 dwConnID, CRpc& roRpc)
{
	int dataSize = roRpc.Serialize(buffer, sizeof(buffer));
	if (dataSize < 0)
	{
		LogError("serialize rpc [%u] failed.", roRpc.m_dwType);
		return false;
	}
	roRpc.OnSend();
	UINT32  dwLength = dataSize + sizeof(UINT32) * 3 + sizeof(SessionType);
	UINT32  dwType = roRpc.m_dwType;
	UINT32  dwFlag = (roRpc.GetEndType() == RPC_CLIENT) ? RPC_TYPE_REQUEST : RPC_TYPE_REPLY;
	UINT32  dwTagId = roRpc.m_dwTag;
	SessionType sessionID = roRpc.m_sessionID;
	MemoryStream* pMemoryStream = MemoryStream::ObjPool().createObject();
	(*pMemoryStream) << dwLength;
	(*pMemoryStream) << dwType;
	(*pMemoryStream) << dwFlag;
	(*pMemoryStream) << sessionID;
	(*pMemoryStream) << dwTagId;
	pMemoryStream->append(buffer, dataSize);

	LogDebug("BaseLink::Send CRpc dwType:%u, dataSize:%d, dwFlag:%u, dwTagId:%u", dwType, pMemoryStream->length(), dwFlag, dwTagId);
	bool result = CNetProcessor::Instance()->Send(dwConnID, pMemoryStream->data(), pMemoryStream->length());
	MemoryStream::ObjPool().reclaimObject(pMemoryStream);
	return result;
}

HeadStruct BaseLink::DecodeHead(UINT32 dwConnID, const char* pcData, UINT32 dwLen)
{
	HeadStruct RetInfo;

	ProtocolHead head;
	memcpy(&head, pcData, sizeof(head));

	if ((head.m_dwFlag & RPC_TYPE_FLAG))
	{
		RpcHead rpcHead;
		memcpy(&rpcHead, pcData, sizeof(RpcHead));

		RetInfo.m_IsPtcHead = false;
		RetInfo.m_dwHeadSize = sizeof(RpcHead);
		RetInfo.m_oRpcHead.m_dwType = rpcHead.m_dwType;
		RetInfo.m_oRpcHead.m_dwLen = rpcHead.m_dwLen;
		RetInfo.m_oRpcHead.m_dwFlag = rpcHead.m_dwFlag;
		RetInfo.m_oRpcHead.m_dwTagID = rpcHead.m_dwTagID;
		RetInfo.m_oRpcHead.m_dwSessionID = rpcHead.m_dwSessionID;
	}
	else
	{
		RetInfo.m_IsPtcHead = true;
		RetInfo.m_dwHeadSize = sizeof(ProtocolHead);
		RetInfo.m_oPtcHead.m_dwType = head.m_dwType;
		RetInfo.m_oPtcHead.m_dwLen = head.m_dwLen;
		RetInfo.m_oPtcHead.m_dwFlag = head.m_dwFlag;
		RetInfo.m_oPtcHead.m_dwSessionID = head.m_dwSessionID;
	}

	return RetInfo;
}

UINT32 BaseLink::MinSize()
{
	return 0;
}

void BaseLink::OnRecv(UINT32 dwConnID, const char* pcData, UINT32 dwLen)
{

}

void BaseLink::SetForwardInterface(ForwardInterface* i)
{
	m_pForwardInterface = i;
}

ForwardInterface* BaseLink::GetForwardInterface()
{
	return m_pForwardInterface;
}

void BaseLink::SetPrintProtocol(bool flag)
{

}

void BaseLink::AddPrintIgnoreProtocol(UINT32 proto)
{

}

BaseLink::PtcResult BaseLink::OnProtocol(RecvParament& parament)
{
	return BaseLink::PTCRES_SUCCESS;
}

BaseLink::PtcResult BaseLink::OnRpc(RecvParament& parament)
{
	return BaseLink::PTCRES_SUCCESS;
}

void BaseLink::ForwardProtocol(UINT32 dwConnID, DataBlob* rawPacket, DataBlob* protoBody, ProtocolHead& head)
{

}

void BaseLink::ForwardRpc(UINT32 dwConnID, DataBlob* rawPacket, DataBlob* protoBody, RpcHead& head)
{

}
